﻿using NotifyAppBase;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace QingPalaceMap
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        //清空图的年龄栏是按照虚岁的年龄来计算的。
        //（科普：古人讲究孝道，特将怀胎十月的时间也算进自己的年龄，以表达对母亲的感谢）
        //清宫图中的月份是妈妈受孕的月份，若妈妈不确定具体的时间，也可以咨询专业医生来查询。
        //如果妈妈受孕的月份恰好是闰月，则上半月时间计作本月，下半月时间计作下月之中
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var list = LoadData();
            RItemsSource=new ObservableCollection<RModel>(list);

            List<int> ages = new List<int>();
            for (int i = 18; i <= 45; i++) { ages.Add(i); }
            AgeItemsSource=new ObservableCollection<int>(ages);

            List<int> monthes = new List<int>();
            for (int i = 1; i <= 12; i++) { monthes.Add(i); }
            MonthItemsSource=new ObservableCollection<int>(monthes);

            TestData();
        }


        /// <summary>
        /// 推算
        /// </summary>
        public void CacDate()
        {



        }


        /// <summary>
        /// 验证
        /// </summary>
        public void TestData()
        {
            var db = LoadData();
            var tda = LoadTestDatas();
            foreach (var item in tda)
            {
                item.Cac();

                var matchItem = db.FirstOrDefault(x => x.Age==item.PAge&& x.Month==item.PMonth);
                if (matchItem!=null)
                {
                    item.IsRight= item.Sex==matchItem.Sex;
                }
            }

        }

        public List<PModel> LoadTestDatas()
        {
            List<PModel> result = new List<PModel>();
            result.Add(new PModel { MomBirthdayChinese =new DateTime(1964, 9, 18), ChildBirthDate=new DateTime(1985, 3, 5), Sex=1 });//19850305
            result.Add(new PModel { MomBirthdayChinese =new DateTime(1964, 9, 18), ChildBirthDate=new DateTime(1988, 12, 28), Sex=0 });//19881228
            result.Add(new PModel { MomBirthdayChinese =new DateTime(1964, 9, 18), ChildBirthDate=new DateTime(1989, 4, 11), Sex=0 });//19890411
            result.Add(new PModel { MomBirthdayChinese =new DateTime(1964, 9, 18), ChildBirthDateChinese=new DateTime(1992, 2, 2), Sex=1 });//19920202
            return result;
        }

        public List<RModel> LoadData()
        {
            List<RModel> result = new List<RModel>();
            var rows = RDataString.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            for (int row = 0; row < rows.Length; row++)
            {
                var columns = rows[row].Split(',');
                for (int column = 0; column < columns.Length; column++)
                {
                    var value = columns[column];
                    result.Add(new RModel
                    {
                        Age=row+18,
                        Month=column+1,
                        Sex=int.Parse(value)
                    });
                }
            }
            return result;
        }



        public DateTime NewDateTime
        {
            get { return (DateTime)GetValue(NewDateTimeProperty); }
            set { SetValue(NewDateTimeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NewDateTime.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewDateTimeProperty =
            DependencyProperty.Register("NewDateTime", typeof(DateTime), typeof(MainWindow), new PropertyMetadata(DateTime.Now));



        public DateTime ChineseDateTime
        {
            get { return (DateTime)GetValue(ChineseDateTimeProperty); }
            set { SetValue(ChineseDateTimeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ChineseDateTime.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ChineseDateTimeProperty =
            DependencyProperty.Register("ChineseDateTime", typeof(DateTime), typeof(MainWindow), new PropertyMetadata(DateTime.Now));



        public int GirlAge
        {
            get { return (int)GetValue(GirlAgeProperty); }
            set { SetValue(GirlAgeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for GirlAge.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GirlAgeProperty =
            DependencyProperty.Register("GirlAge", typeof(int), typeof(MainWindow), new PropertyMetadata(0));


        //RelationShip

        public ObservableCollection<RModel> RItemsSource
        {
            get { return (ObservableCollection<RModel>)GetValue(RItemsSourceProperty); }
            set { SetValue(RItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RItemsSourceProperty =
            DependencyProperty.Register("RItemsSource", typeof(ObservableCollection<RModel>), typeof(MainWindow), new PropertyMetadata(null));



        public ObservableCollection<int> AgeItemsSource
        {
            get { return (ObservableCollection<int>)GetValue(AgeItemsSourceProperty); }
            set { SetValue(AgeItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AgeItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AgeItemsSourceProperty =
            DependencyProperty.Register("AgeItemsSource", typeof(ObservableCollection<int>), typeof(MainWindow), new PropertyMetadata(null));




        public ObservableCollection<int> MonthItemsSource
        {
            get { return (ObservableCollection<int>)GetValue(MonthItemsSourceProperty); }
            set { SetValue(MonthItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MonthItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MonthItemsSourceProperty =
            DependencyProperty.Register("MonthItemsSource", typeof(ObservableCollection<int>), typeof(MainWindow), new PropertyMetadata(null));

        public List<PModel> TestDatas { get; set; } = new List<PModel>();


        string RDataString =
             // 2 3 4 5 6 7 8 9
             //                 10
             //                   11
             //                     12
             "0,1,0,1,1,1,1,1,1,1,1,1"+Environment.NewLine //18
            +"1,0,1,0,0,1,1,1,1,1,0,0"+Environment.NewLine //19 
            +"0,1,0,1,1,1,1,1,1,0,1,1"+Environment.NewLine //20
            +"1,0,0,0,0,0,0,0,0,0,0,0"+Environment.NewLine //21
            +"0,1,1,0,1,0,0,1,0,0,0,0"+Environment.NewLine //22
            +"1,1,0,1,1,0,1,0,1,1,1,0"+Environment.NewLine //23
            +"1,0,1,1,0,1,1,0,0,0,0,0"+Environment.NewLine //24
            +"0,1,1,0,0,1,0,1,1,1,1,1"+Environment.NewLine //25
            +"1,0,1,0,0,1,0,1,0,0,0,0"+Environment.NewLine //26
            +"0,1,0,1,0,0,1,1,1,1,0,1"+Environment.NewLine //27
            +"1,0,1,0,0,0,1,1,1,1,0,0"+Environment.NewLine //28
            +"0,1,0,0,1,1,1,1,1,0,0,0"+Environment.NewLine //29
            +"1,0,0,0,0,0,0,0,0,0,1,1"+Environment.NewLine //30
            +"1,0,1,0,0,0,0,0,0,0,0,1"+Environment.NewLine //31
            +"1,0,1,0,0,0,0,0,0,0,0,1"+Environment.NewLine //32
            +"0,1,0,1,0,0,0,1,0,0,0,1"+Environment.NewLine //33
            +"1,0,1,0,0,0,0,0,0,0,1,1"+Environment.NewLine //34
            +"1,1,0,1,0,0,0,1,0,0,1,1"+Environment.NewLine //35
            +"0,1,1,0,1,0,0,0,1,1,1,1"+Environment.NewLine //36
            +"1,0,1,1,0,1,0,1,0,1,0,1"+Environment.NewLine //37
            +"0,1,0,1,1,0,1,0,1,0,1,0"+Environment.NewLine //38
            +"1,0,1,1,1,0,0,1,0,1,0,0"+Environment.NewLine //39
            +"0,1,0,1,0,1,1,0,1,0,1,0"+Environment.NewLine //40
            +"1,0,1,0,1,0,1,1,0,1,0,1"+Environment.NewLine //41
            +"0,1,0,1,0,1,0,1,1,0,1,0"+Environment.NewLine //42
            +"1,0,1,0,1,0,1,0,1,1,1,1"+Environment.NewLine //43
            +"1,1,0,1,1,1,0,1,0,1,0,0"+Environment.NewLine //44
            +"0,1,1,0,0,0,1,0,1,0,1,1"+Environment.NewLine //45
            ;


        public enum Sex
        {
            Farman = 0,
            Man = 1,
        }


        public class RModel : ObservableObject
        {
            private int _Age;
            public int Age { get => _Age; set => Set(ref _Age, value); }

            private int _Month;
            public int Month { get => _Month; set => Set(ref _Month, value); }

            private int _Sex;
            public int Sex { get => _Sex; set => Set(ref _Sex, value); }

        }

        //Pregnant
        public class PModel : ObservableObject
        {
            private DateTime _Birthday;
            public DateTime MonBirthday { get => _Birthday; set => Set(ref _Birthday, value); }

            private DateTime _BirthdayChinese;
            public DateTime MomBirthdayChinese { get => _BirthdayChinese; set => Set(ref _BirthdayChinese, value); }

            private DateTime _PDateTime;
            public DateTime ChildBirthDate { get => _PDateTime; set => Set(ref _PDateTime, value); }

            private DateTime _PDateTimeChinese;
            public DateTime ChildBirthDateChinese { get => _PDateTimeChinese; set => Set(ref _PDateTimeChinese, value); }

            private int _PAge;
            /// <summary>
            /// chinese
            /// </summary>
            public int PAge { get => _PAge; set => Set(ref _PAge, value); }

            private int _PMonth;
            /// <summary>
            /// chinese
            /// </summary>
            public int PMonth { get => _PMonth; set => Set(ref _PMonth, value); }

            private int _Sex;

            public int Sex { get => _Sex; set => Set(ref _Sex, value); }

            private bool _IsRight;
            /// <summary>
            /// 是否正确
            /// </summary>
            public bool IsRight { get => _IsRight; set => Set(ref _IsRight, value); }

            public DateTime GetBirthdayChinese()
            {
                MomBirthdayChinese=DateConvertToChinese(MonBirthday);
                PAge= (int)Math.Ceiling((DateTime.Now-MonBirthday).TotalDays/365);
                return MomBirthdayChinese;
            }


            public void Cac()
            {
                if (ChildBirthDate!=DateTime.MinValue)
                {
                    ChildBirthDateChinese=DateConvertToChinese(ChildBirthDate);
                    PMonth= ChildBirthDateChinese.AddMonths(-10).Month;
                }
                else if (ChildBirthDateChinese!=DateTime.MinValue)
                {
                    ChildBirthDate=ChineseConvertToDate(ChildBirthDateChinese);
                    PMonth= ChildBirthDateChinese.AddMonths(-10).Month;
                }


                if (MonBirthday!= DateTime.MinValue)
                {
                    MomBirthdayChinese=DateConvertToChinese(MonBirthday);
                    PAge= (ChildBirthDate.AddMonths(-10).Year-MonBirthday.Year)+1;
                    //PAge= (int)Math.Ceiling((ChildBirthDate.AddMonths(-10)-MonBirthday).TotalDays/365);
                }
                else if (MomBirthdayChinese!= DateTime.MinValue)
                {
                    MonBirthday=ChineseConvertToDate(MomBirthdayChinese);
                    PAge= (ChildBirthDate.AddMonths(-10).Year-MonBirthday.Year)+1;
                    //PAge= (int)Math.Ceiling((ChildBirthDate.AddMonths(-10)-MonBirthday).TotalDays/365);
                }


            }

            public override string ToString()
            {
                return $"age{this.PAge} month{this.PMonth} sex{this.Sex} right{this.IsRight}";
            }

        }

        //private void DatePicker_SelectedDateChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        //{
        //    ChineseDateTime=DateConvertToChinese(NewDateTime);
        //}

        //private void ChineseDatePicker_SelectedDateChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        //{
        //    NewDateTime=ChineseConvertToDate(ChineseDateTime);
        //}
        private void DatePicker_SelectedDateChanged(object sender, RoutedEventArgs e)
        {
            ChineseDateTime=DateConvertToChinese(NewDateTime);
            GirlAge= (int)Math.Ceiling((DateTime.Now-NewDateTime).TotalDays/365);
        }

        private void ChineseDatePicker_SelectedDateChanged(object sender, RoutedEventArgs e)
        {
            NewDateTime=ChineseConvertToDate(ChineseDateTime);
            GirlAge= (int)Math.Ceiling((DateTime.Now-NewDateTime).TotalDays/365);
        }

        /// <summary>
        /// 阳历转农历
        /// </summary>
        public static DateTime DateConvertToChinese(DateTime dateTime)
        {
            ChineseLunisolarCalendar cncld = new ChineseLunisolarCalendar();
            DateTime dt = dateTime;
            int year = cncld.GetYear(dt);
            // 是否有闰月,返回正整数（2020年闰4月，返回值为5）
            int flag = cncld.GetLeapMonth(year);
            int month = flag > 0 ? cncld.GetMonth(dt) - 1 : cncld.GetMonth(dt);
            int day = cncld.GetDayOfMonth(dt);
            Console.WriteLine($"{dt:d}，农历：{year}年{month}月{day}日");
            return new DateTime(year, month, day);
        }

        /// <summary>
        /// 农历转阳历
        /// </summary>
        public static DateTime ChineseConvertToDate(DateTime dateTime)
        {
            ChineseLunisolarCalendar cncld = new ChineseLunisolarCalendar();
            DateTime dt = dateTime;
            int year = cncld.GetYear(dt);
            // 是否有闰月,返回正整数（2020年闰4月，返回值为5）
            int flag = cncld.GetLeapMonth(year);
            int month = flag > 0 ? cncld.GetMonth(dt) - 1 : cncld.GetMonth(dt);
            int day = cncld.GetDayOfMonth(dt);

            DateTime dtnl = cncld.ToDateTime(year, month, day, 0, 0, 0, 0);
            dtnl = flag > 0 ? dtnl.AddMonths(1) : dtnl;
            Console.WriteLine($"{dtnl}");
            return dtnl;
        }






    }
}
